package com.ljk.util.pdf.data;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import com.itextpdf.text.pdf.draw.LineSeparator;
import com.ljk.util.array.CollectionUtil;
import com.ljk.util.pdf.PdfUtil;
import com.ljk.util.pdf.template.PdfTemplate;
import com.ljk.util.string.StringUtil;

import java.io.OutputStream;
import java.util.Collections;
import java.util.List;
import java.util.StringJoiner;

public abstract class BasePresTemplate<T extends BasePrescription<?>> implements PdfTemplate<T> {

    @Override
    public void generatePdf(OutputStream os, T pres) throws DocumentException {
        final BaseFont baseFont = PdfUtil.getBaseFont();
        // 创建PDF文档
        Document document = new Document(PageSize.A4);
        document.setMargins(10, 10, 10, 10);

        // 创建PDF写入器
        PdfWriter writer = PdfWriter.getInstance(document, os);
        // 打开文档
        document.open();

        //文档的具体坐标
        float docWidth = document.right() - document.left();//可用宽度
        float docHeight = document.top() - document.bottom();//可用高度
        float leftMargin = document.leftMargin();//左边距
        float rightMargin = document.rightMargin();//右边距
        float topMargin = document.topMargin();//上边距
        float bottomMargin = document.bottomMargin();//下边距
        //获取画板
        PdfContentByte cb = writer.getDirectContent();

        // 设置画板内头部的坐标和大小
        float height = 73.6f;
        float width = docWidth;
        float x = document.left();
        float y = docHeight - height;
        // 绘制画板
//        cb.rectangle(x, y, width, height);
//        cb.stroke();

        //右上角处方类别
        cb.ellipse(x + width - 42, y + height - 21, x + width-5, y + height-4.5);//画个圆

        cb.beginText();
        cb.setFontAndSize(baseFont, 12);
        cb.setCharacterSpacing(0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, pres.getTypeName(), x + width - 23, y + height - 16.5f, 0);
        // 结束文字绘制
        cb.endText();

        List<String> markList = pres.getCornerMarkList()==null? Collections.emptyList():pres.getCornerMarkList();
        if (!markList.isEmpty()){
            cb.rectangle(x+width-40, y+30, 37, 16.5);
            cb.beginText();
            cb.showTextAligned(PdfContentByte.ALIGN_LEFT, markList.get(0), x+width-40+5.5f, y+30+4, 0);
            cb.endText();
            if (markList.size()>1) {
                cb.rectangle(x+width-40-40, y+30, 37, 16.5);
                cb.beginText();
                cb.showTextAligned(PdfContentByte.ALIGN_LEFT, markList.get(1), x+width-40-40+5.5f, y+30+4, 0);
                cb.endText();
            }
        }
        cb.beginText();

        // 院区名称
        cb.setFontAndSize(baseFont, 15);
        cb.setCharacterSpacing(0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, pres.getDeptName(), x + width / 2, y + height - 16, 0);
        //处方标题
        cb.setFontAndSize(baseFont, 20);
        cb.setCharacterSpacing(9.2f);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, pres.getTitle(), x + width / 2, y + 18f, 0);


        if (pres.getPrescriptionNo() != null) {
            cb.setCharacterSpacing(0);
            cb.setFontAndSize(baseFont, 12);
            cb.showTextAligned(PdfContentByte.ALIGN_RIGHT, "No. " + pres.getPrescriptionNo(), x + width - 13.8f, y + 12 / 2f - 1, 0);
        }
        cb.endText();
        PdfUtil.createBlank(document, height + topMargin);

//        float totalWidth = 370;
        float widthPercentage = 98f;
        PdfPTable headTable = new PdfPTable(1);
        headTable.setWidthPercentage(widthPercentage);

        //头部字体大小
        Font font = new Font(baseFont, 11, Font.NORMAL);
        float[] relativeWidths = {5, 8};

        {//第一行
            PdfPCell cell1 = PdfUtil.parseOneCell(relativeWidths, PdfUtil.createCell(font, "科别", Element.ALIGN_LEFT), PdfUtil.createCell(font, pres.getSectionName(), Element.ALIGN_LEFT));
            PdfPCell cell2 = PdfUtil.parseOneCell(relativeWidths, PdfUtil.createCell(font, "费别", Element.ALIGN_LEFT), PdfUtil.createCell(font, pres.getRecordTypeDicStr(), Element.ALIGN_LEFT));
            PdfPCell cell3 = PdfUtil.parseOneCell(PdfUtil.createCell(font, "门诊号", Element.ALIGN_LEFT), PdfUtil.createCell(font, pres.getPatientNo(), Element.ALIGN_LEFT));
            PdfPCell cell4 = PdfUtil.createCell(font, pres.getStartTime(), Element.ALIGN_CENTER);
            PdfPCell cell = PdfUtil.parseOneCell(cell1, cell2, cell3, cell4);
            cell.setBorder(Rectangle.BOTTOM);
            cell.setPaddingBottom(3);
            headTable.addCell(cell);
        }
        boolean containsPsychotropicDrugs = "精二".equals(pres.getTypeName()) || (!markList.isEmpty() && markList.contains("局麻"));
        {//第二行
            PdfPCell cell1 = PdfUtil.parseOneCell(relativeWidths, PdfUtil.createCell(font, "姓名", Element.ALIGN_LEFT), PdfUtil.createCell(font, pres.getPatientName(), Element.ALIGN_LEFT));
            PdfPCell cell2 = PdfUtil.parseOneCell(relativeWidths, PdfUtil.createCell(font, "年龄", Element.ALIGN_RIGHT), PdfUtil.createCell(font, pres.getAge(), Element.ALIGN_LEFT));
            PdfPCell cell3 = PdfUtil.parseOneCell(relativeWidths, PdfUtil.createCell(font, "性别", Element.ALIGN_RIGHT), PdfUtil.createCell(font, pres.getSex(), Element.ALIGN_LEFT));
            PdfPCell cell4;
            if (StringUtil.isNotEmpty(pres.getWeight())) {
                cell4 = PdfUtil.parseOneCell(relativeWidths, PdfUtil.createCell(font, "体重", Element.ALIGN_RIGHT), PdfUtil.createCell(font, pres.getWeight() + "kg", Element.ALIGN_LEFT));
            } else {
                cell4 = PdfUtil.createCell(font, "", Element.ALIGN_CENTER);
            }
            PdfPCell cell;
            if (containsPsychotropicDrugs){
                PdfPCell cell5 = PdfUtil.parseOneCell(relativeWidths, PdfUtil.createCell(font, "身份证号", Element.ALIGN_RIGHT), PdfUtil.createCell(font, pres.getAgentIdNo(), Element.ALIGN_LEFT));
                cell = PdfUtil.parseOneCell(new float[]{3, 2, 2, 2, 4}, cell1, cell2, cell3, cell4, cell5);
            }else {
                cell = PdfUtil.parseOneCell(cell1, cell2, cell3, cell4);
            }
            cell.setBorder(Rectangle.BOTTOM);
            cell.setPaddingBottom(3);
            headTable.addCell(cell);
        }
        if (containsPsychotropicDrugs) {
            PdfPCell cell1 = PdfUtil.parseOneCell(new float[]{3, 4}, PdfUtil.createCell(font, "代办人姓名", Element.ALIGN_LEFT), PdfUtil.createCell(font, pres.getAgentName(), Element.ALIGN_LEFT));
            PdfPCell cell2 = PdfUtil.parseOneCell(new float[]{2, 7}, PdfUtil.createCell(font, "代办人证件号", Element.ALIGN_LEFT), PdfUtil.createBankCell());
            PdfPCell cell = PdfUtil.parseOneCell(new float[]{2, 4}, cell1, cell2);
            cell.setBorder(Rectangle.BOTTOM);
            cell.setPaddingBottom(3);
            headTable.addCell(cell);
        }
        {//诊断行
//            String diagStr = "头痛; 高风雀目病(太阳痰气痞证);";
            String diagStr = pres.getDiagName();
            PdfPCell cell = PdfUtil.parseOneCell(new float[]{15, 85}, PdfUtil.createCell(font, "临床诊断", Element.ALIGN_LEFT), PdfUtil.createCell(font, diagStr, Element.ALIGN_LEFT));
            cell.setBorder(Rectangle.BOTTOM);
            cell.setBorderWidthBottom(2);
            cell.setPaddingBottom(5);
            headTable.addCell(cell);
        }
        document.add(headTable);


        PdfPTable presTable = new PdfPTable(1);
        presTable.setWidthPercentage(widthPercentage);
        presTable.addCell(PdfUtil.createCell(new Font(baseFont, 18, Font.NORMAL), "R", Element.ALIGN_LEFT));

        //处方明细
        if (!CollectionUtil.isEmpty(pres.getPresList())) {
//            PdfPCell leftCell = PdfUtil.createCell(font, "", Element.ALIGN_LEFT);
//            PdfPTable rightTable = new PdfPTable(1);
            float[] leftRightWidth = {4, 96};
            convertItem(baseFont, pres, presTable, leftRightWidth);
//            presTable.addCell(PdfUtil.parseOneCell(new float[]{4, 96}, leftCell, PdfUtil.parseCell4Table(rightTable)));
        }

        //空白提示线
        PdfPTable lineTable = new PdfPTable(new float[]{32, 10, 32});
        LineSeparator line = new LineSeparator(1, 100, BaseColor.BLACK, Element.ALIGN_CENTER, 0);
        lineTable.addCell(PdfUtil.parseCell(new Phrase(new Chunk(line))));
        lineTable.addCell(PdfUtil.createCell(new Font(baseFont, 10, Font.NORMAL), "以下空白", Element.ALIGN_CENTER));
        lineTable.addCell(PdfUtil.parseCell(new Phrase(new Chunk(line))));
        presTable.addCell(PdfUtil.parseCell4Table(lineTable));
        document.add(presTable);


//        System.out.println("一页总高度 = " + docHeight);
//        System.out.println("title height = " + height);
//        System.out.println("前三行表格高度headTable.getTotalHeight() = " + headTable.getTotalHeight());
//        System.out.println("处方高度presTable.getTotalHeight() = " + presTable.getTotalHeight());
        float canUseHeight = docHeight - height - headTable.getTotalHeight() - presTable.getTotalHeight();//可用高度
//        System.out.println("可用高度:" + canUseHeight);
        if (canUseHeight <= 0) {
            canUseHeight = 30;
        } else if (canUseHeight > 100) {
            canUseHeight -= 100;//100是尾部高度加上冗余30
        }
//        System.out.println("空白高度(计算后):" + canUseHeight);
        PdfUtil.createBlank(document, (canUseHeight));


        PdfPTable endTable = new PdfPTable(1);
        endTable.setWidthPercentage(widthPercentage);
        endTable.addCell(PdfUtil.parseCell(new LineSeparator(2, 100, BaseColor.BLACK, Element.ALIGN_CENTER, 0)));

        {
            PdfPCell doctorK = PdfUtil.createCell(font, "医师", Element.ALIGN_LEFT);
            PdfPCell doctorV;
            List<SignData> doctorList = pres.getDoctorList();
            if (CollectionUtil.isEmpty(doctorList)) {
                doctorV = PdfUtil.createCell(font, "", Element.ALIGN_CENTER);
            } else if (doctorList.size() == 1) {
                doctorV = PdfUtil.createSignCell(font, doctorList.get(0));
            } else {
                SignData signData1 = doctorList.get(0);
                SignData signData2 = doctorList.get(1);
                PdfPCell cell1 = PdfUtil.createSignCell(font, signData1);
                PdfPCell cell2 = PdfUtil.createSignCell(font, signData2);
                cell1.setHorizontalAlignment(Element.ALIGN_RIGHT);
                cell2.setHorizontalAlignment(Element.ALIGN_LEFT);
                if (signData1.getType() == SignType.string) {
                    doctorV = PdfUtil.parseOneCell(new float[]{10, 1, 10}, cell1, PdfUtil.createCell(font, "/", Element.ALIGN_CENTER), cell2);
                } else {
                    doctorV = PdfUtil.parseOneCell(cell1, cell2);
                    doctorV.setFixedHeight(25);
                }
            }
            doctorV.setBorder(Rectangle.BOTTOM);
            PdfPCell auditK = PdfUtil.createCell(font, "审核", Element.ALIGN_LEFT);
            PdfPCell auditV = PdfUtil.createSignCell(font, pres.getAudit());
            auditV.setBorder(Rectangle.BOTTOM);
            auditV.setPaddingBottom(3);
            PdfPCell priceK = PdfUtil.createCell(font, "金额", Element.ALIGN_LEFT);
            PdfPCell priceV = PdfUtil.createCell(font, String.valueOf(pres.getTotalPrice()), Element.ALIGN_CENTER);
            priceV.setBorder(Rectangle.BOTTOM);
            priceV.setPaddingBottom(3);
            PdfPCell deployK = PdfUtil.createCell(font, "调配", Element.ALIGN_LEFT);
            PdfPCell deployV = PdfUtil.createSignCell(font, pres.getDeploy());
            deployV.setBorder(Rectangle.BOTTOM);
            deployV.setPaddingBottom(3);
            PdfPCell checkK = PdfUtil.createCell(font, "核对", Element.ALIGN_LEFT);
            PdfPCell checkV = PdfUtil.createSignCell(font, pres.getCheck());
            checkV.setBorder(Rectangle.BOTTOM);
            checkV.setPaddingBottom(3);
            PdfPCell sendDrugK = PdfUtil.createCell(font, "发药", Element.ALIGN_LEFT);
            PdfPCell sendDrugV = PdfUtil.createSignCell(font, pres.getSendDrug());
            sendDrugV.setBorder(Rectangle.BOTTOM);
            sendDrugV.setPaddingBottom(3);

            PdfPCell cell = PdfUtil.parseOneCell(new float[]{5, 25, 5, 15, 5, 15}, doctorK, doctorV, auditK, auditV, priceK, priceV);
            cell.setVerticalAlignment(Element.ALIGN_BOTTOM);
//            cell.setBorder(Rectangle.BOX);
            cell.setFixedHeight(27);
            endTable.addCell(cell);
            endTable.addCell(PdfUtil.parseOneCell(new float[]{5, 25, 5, 15, 5, 15}, deployK, deployV, checkK, checkV, sendDrugK, sendDrugV));
        }


        {
            Font descFont = new Font(baseFont, 9, Font.NORMAL);
            PdfPCell cell1 = PdfUtil.createCell(descFont, "注意:", Element.ALIGN_TOP, Element.ALIGN_LEFT);
            PdfPCell cell2 = PdfUtil.createCell(descFont, "1、处方开具后24小时内有效。\n2、如所开处方超过7日量，请注明原因:慢性病、老年病、外地、其他。", Element.ALIGN_LEFT);
            endTable.addCell(PdfUtil.parseOneCell(new float[]{7, 72}, cell1, cell2));
        }

        document.add(endTable);


//        System.out.println("endTable.getTotalHeight() = " + endTable.getTotalHeight());
        // 关闭文档
        document.close();
    }


    public abstract int convertItem(BaseFont baseFont, T pres, PdfPTable rightTable, float[] leftRightWidth);


    protected static String joinParam(String delimiter, String... params) {
        StringJoiner sj = new StringJoiner(delimiter);
        for (String param : params) {
            if (StringUtil.isNotEmpty(param)) {
                sj.add(param);
            }
        }
        return sj.toString();
    }
}
